/**
 * 重新设计的图表数据管理器
 * 核心思想：历史数据和实时数据分离管理，统一显示
 */
class ChartDataManager {
  constructor(options = {}) {
    // 配置参数
    this.displayWindowSize = options.displayWindowSize || 600; // 显示窗口大小
    this.historicalDataRetention = options.historicalDataRetention || 24 * 60 * 60 * 1000; // 历史数据保留时间（24小时）
    this.realtimeDataRetention = options.realtimeDataRetention || 60 * 60 * 1000; // 实时数据保留时间（1小时）
    this.updateThrottle = options.updateThrottle || 100; // 更新节流间隔

    // 数据存储结构
    this.devices = new Map(); // 设备数据存储

    // 状态管理
    this.lastUpdateTime = 0;
    this.pendingUpdates = new Set();
    this.updateCallback = null;

    // 绑定方法
    this.throttledUpdate = this.throttle(this.triggerUpdate.bind(this), this.updateThrottle);

    console.log('📊 ChartDataManager 已初始化', options);
  }

  /**
   * 初始化设备数据结构
   */
  initializeDevice(deviceId, metadata = {}) {
    if (!this.devices.has(deviceId)) {
      const deviceData = {
        // 设备元数据
        metadata: {
          latheName: metadata.latheName || '',
          putPlace: metadata.putPlace || '',
          deviceLocation: metadata.deviceLocation || '',
          bindLocation: metadata.bindLocation || '',
          ...metadata
        },

        // 历史数据存储（有序数组，按时间排序）
        historicalData: {
          timestamps: [], // 时间戳数组
          rms: { x: [], y: [], z: [] }, // RMS数据
          peak: { x: [], y: [], z: [] }, // Peak数据
          isLoaded: false, // 是否已加载历史数据
          loadTime: null, // 加载时间
          timeRange: { start: null, end: null } // 时间范围
        },

        // 实时数据存储（有序数组，按时间排序）
        realtimeData: {
          timestamps: [], // 时间戳数组
          rms: { x: [], y: [], z: [] }, // RMS数据
          peak: { x: [], y: [], z: [] }, // Peak数据
          lastUpdateTime: 0, // 最后更新时间
          dataCount: 0 // 数据点数量
        },

        // 显示状态
        displayState: {
          currentWindowStart: null, // 当前显示窗口开始时间
          currentWindowEnd: null, // 当前显示窗口结束时间
          autoScroll: true, // 是否自动滚动到最新数据
          lastRenderTime: 0 // 最后渲染时间
        }
      };

      this.devices.set(deviceId, deviceData);
      console.log(`📊 设备 ${deviceId} 数据结构已初始化`);
    }

    return this.devices.get(deviceId);
  }

  /**
   * 加载历史数据
   */
  loadHistoricalData(deviceId, rawHistoricalData) {
    const device = this.initializeDevice(deviceId);
    const processedData = this.processHistoricalData(rawHistoricalData);

    if (processedData.length === 0) {
      console.warn(`⚠️ 设备 ${deviceId} 历史数据为空`);
      return;
    }

    // 清空现有历史数据
    this.clearHistoricalData(deviceId);

    // 批量插入历史数据
    const historical = device.historicalData;
    processedData.forEach(point => {
      historical.timestamps.push(point.timestamp);
      historical.rms.x.push(point.rms.x);
      historical.rms.y.push(point.rms.y);
      historical.rms.z.push(point.rms.z);
      historical.peak.x.push(point.peak.x);
      historical.peak.y.push(point.peak.y);
      historical.peak.z.push(point.peak.z);
    });

    // 更新历史数据状态
    historical.isLoaded = true;
    historical.loadTime = Date.now();
    historical.timeRange.start = processedData[0].timestamp;
    historical.timeRange.end = processedData[processedData.length - 1].timestamp;

    // 设置显示窗口覆盖完整的历史数据范围
    device.displayState.currentWindowStart = historical.timeRange.start;
    device.displayState.currentWindowEnd = historical.timeRange.end;

    console.log(`📈 设备 ${deviceId} 历史数据加载完成`, {
      dataPoints: processedData.length,
      timeRange: {
        start: new Date(historical.timeRange.start).toLocaleString(),
        end: new Date(historical.timeRange.end).toLocaleString()
      }
    });

    // 触发更新
    this.addPendingUpdate(deviceId);
    this.throttledUpdate();
  }

  /**
   * 处理历史数据 - 清洗、排序、去重
   */
  processHistoricalData(rawData) {
    if (!Array.isArray(rawData) || rawData.length === 0) {
      return [];
    }

    // 标准化数据格式
    const normalizedData = rawData
      .map(item => this.normalizeDataPoint(item))
      .filter(item => item && item.timestamp); // 过滤无效数据

    // 按时间排序
    normalizedData.sort((a, b) => a.timestamp - b.timestamp);

    // 去重（相同时间戳的数据只保留最后一个）
    const deduplicatedData = [];
    let lastTimestamp = null;

    for (const item of normalizedData) {
      if (item.timestamp !== lastTimestamp) {
        deduplicatedData.push(item);
        lastTimestamp = item.timestamp;
      } else {
        // 相同时间戳，替换为最新数据
        deduplicatedData[deduplicatedData.length - 1] = item;
      }
    }

    console.log(`📊 历史数据处理完成: ${rawData.length} -> ${deduplicatedData.length}`);
    return deduplicatedData;
  }

  /**
   * 添加实时数据点
   */
  addRealtimeData(deviceId, rawData) {
    const device = this.initializeDevice(deviceId);
    const dataPoint = this.normalizeDataPoint(rawData);

    if (!dataPoint || !dataPoint.timestamp) {
      console.warn(`⚠️ 无效的实时数据:`, rawData);
      return false;
    }

    const realtime = device.realtimeData;
    const historical = device.historicalData;

    // 验证时间戳顺序（实时数据应该比历史数据更新）
    if (historical.isLoaded && dataPoint.timestamp <= historical.timeRange.end) {
      console.warn(`⚠️ 实时数据时间戳异常: ${dataPoint.timestamp} <= ${historical.timeRange.end}`);
      return false;
    }

    // 检查是否是重复数据
    if (realtime.timestamps.length > 0) {
      const lastTimestamp = realtime.timestamps[realtime.timestamps.length - 1];
      if (dataPoint.timestamp <= lastTimestamp) {
        console.warn(`⚠️ 实时数据时间戳重复或倒序: ${dataPoint.timestamp} <= ${lastTimestamp}`);
        return false;
      }
    }

    // 添加数据点
    this.insertRealtimeDataPoint(device, dataPoint);

    // 清理过期数据
    this.cleanupExpiredRealtimeData(device);

    // 更新显示窗口（扩展到包含新的实时数据）
    if (device.displayState.autoScroll) {
      // 扩展窗口末尾到最新数据
      device.displayState.currentWindowEnd = dataPoint.timestamp;

      // 如果有历史数据，保持从历史数据开始显示
      if (device.historicalData.isLoaded && device.historicalData.timeRange.start) {
        device.displayState.currentWindowStart = device.historicalData.timeRange.start;
      } else {
        // 如果没有历史数据，显示最近10分钟
        device.displayState.currentWindowStart = this.calculateWindowStart(dataPoint.timestamp);
      }
    }

    console.log(`📊 设备 ${deviceId} 实时数据已添加: ${new Date(dataPoint.timestamp).toLocaleTimeString()}`);

    // 触发更新
    this.addPendingUpdate(deviceId);
    this.throttledUpdate();

    return true;
  }

  /**
   * 插入实时数据点（保持时间顺序）
   */
  insertRealtimeDataPoint(device, dataPoint) {
    const realtime = device.realtimeData;

    // 直接追加到末尾（因为已经验证了时间顺序）
    realtime.timestamps.push(dataPoint.timestamp);
    realtime.rms.x.push(dataPoint.rms.x);
    realtime.rms.y.push(dataPoint.rms.y);
    realtime.rms.z.push(dataPoint.rms.z);
    realtime.peak.x.push(dataPoint.peak.x);
    realtime.peak.y.push(dataPoint.peak.y);
    realtime.peak.z.push(dataPoint.peak.z);

    realtime.dataCount++;
    realtime.lastUpdateTime = Date.now();
  }

  /**
   * 清理过期的实时数据
   */
  cleanupExpiredRealtimeData(device) {
    const realtime = device.realtimeData;
    const now = Date.now();
    const cutoffTime = now - this.realtimeDataRetention;

    // 找到第一个未过期的数据点
    let keepFromIndex = 0;
    for (let i = 0; i < realtime.timestamps.length; i++) {
      if (realtime.timestamps[i] >= cutoffTime) {
        keepFromIndex = i;
        break;
      }
    }

    // 如果有数据需要清理
    if (keepFromIndex > 0) {
      realtime.timestamps.splice(0, keepFromIndex);
      realtime.rms.x.splice(0, keepFromIndex);
      realtime.rms.y.splice(0, keepFromIndex);
      realtime.rms.z.splice(0, keepFromIndex);
      realtime.peak.x.splice(0, keepFromIndex);
      realtime.peak.y.splice(0, keepFromIndex);
      realtime.peak.z.splice(0, keepFromIndex);

      realtime.dataCount = realtime.timestamps.length;
      console.log(`🧹 清理了 ${keepFromIndex} 个过期实时数据点`);
    }
  }

  /**
   * 标准化数据点格式
   */
  normalizeDataPoint(rawPoint) {
    if (!rawPoint) return null;

    return {
      timestamp: rawPoint.collectTime || rawPoint.timestamp || Date.now(),
      rms: {
        x: Number(rawPoint.xrms || 0),
        y: Number(rawPoint.yrms || 0),
        z: Number(rawPoint.zrms || 0)
      },
      peak: {
        x: Number(rawPoint.xpeak || 0),
        y: Number(rawPoint.ypeak || 0),
        z: Number(rawPoint.zpeak || 0)
      },
      temperature: rawPoint.temperature ? Number(rawPoint.temperature) : null
    };
  }

  /**
   * 获取显示数据（核心方法）
   */
  getDisplayData(deviceId, dataType = 'rms') {
    const device = this.devices.get(deviceId);
    if (!device) {
      return this.getEmptyDisplayData();
    }

    const windowStart = device.displayState.currentWindowStart;
    const windowEnd = device.displayState.currentWindowEnd;

    if (!windowStart || !windowEnd) {
      return this.getEmptyDisplayData();
    }

    // 合并历史数据和实时数据
    const mergedData = this.mergeHistoricalAndRealtimeData(device, windowStart, windowEnd);

    // 提取指定类型的数据
    const sourceData = dataType === 'rms' ? 'rms' : 'peak';

    // 转换为图表需要的格式，使用智能时间标签生成
    const timeLabels = this.generateUniqueTimeLabels(mergedData.timestamps);

    const displayData = {
      timeData: timeLabels,
      valueData: {
        x: mergedData[sourceData].x,
        y: mergedData[sourceData].y,
        z: mergedData[sourceData].z
      },
      metadata: {
        totalPoints: mergedData.timestamps.length,
        timeRange: { start: windowStart, end: windowEnd },
        hasHistoricalData: device.historicalData.isLoaded,
        hasRealtimeData: device.realtimeData.dataCount > 0
      }
    };

    console.log(`📊 设备 ${deviceId} 显示数据已生成`, {
      type: dataType,
      points: displayData.timeData.length,
      timeRange: {
        start: new Date(windowStart).toLocaleTimeString(),
        end: new Date(windowEnd).toLocaleTimeString()
      }
    });

    return displayData;
  }

  /**
   * 合并历史数据和实时数据（核心算法）
   */
  mergeHistoricalAndRealtimeData(device, windowStart, windowEnd) {
    const historical = device.historicalData;
    const realtime = device.realtimeData;

    const result = {
      timestamps: [],
      rms: { x: [], y: [], z: [] },
      peak: { x: [], y: [], z: [] }
    };

    // 1. 添加窗口范围内的历史数据
    if (historical.isLoaded) {
      for (let i = 0; i < historical.timestamps.length; i++) {
        const timestamp = historical.timestamps[i];
        if (timestamp >= windowStart && timestamp <= windowEnd) {
          result.timestamps.push(timestamp);
          result.rms.x.push(historical.rms.x[i]);
          result.rms.y.push(historical.rms.y[i]);
          result.rms.z.push(historical.rms.z[i]);
          result.peak.x.push(historical.peak.x[i]);
          result.peak.y.push(historical.peak.y[i]);
          result.peak.z.push(historical.peak.z[i]);
        }
      }
    }

    // 2. 添加窗口范围内的实时数据
    for (let i = 0; i < realtime.timestamps.length; i++) {
      const timestamp = realtime.timestamps[i];
      if (timestamp >= windowStart && timestamp <= windowEnd) {
        result.timestamps.push(timestamp);
        result.rms.x.push(realtime.rms.x[i]);
        result.rms.y.push(realtime.rms.y[i]);
        result.rms.z.push(realtime.rms.z[i]);
        result.peak.x.push(realtime.peak.x[i]);
        result.peak.y.push(realtime.peak.y[i]);
        result.peak.z.push(realtime.peak.z[i]);
      }
    }

    // 3. 按时间戳排序（确保时间轴连续）
    const indices = Array.from({ length: result.timestamps.length }, (_, i) => i);
    indices.sort((a, b) => result.timestamps[a] - result.timestamps[b]);

    // 重新排列所有数组
    const sortedResult = {
      timestamps: indices.map(i => result.timestamps[i]),
      rms: {
        x: indices.map(i => result.rms.x[i]),
        y: indices.map(i => result.rms.y[i]),
        z: indices.map(i => result.rms.z[i])
      },
      peak: {
        x: indices.map(i => result.peak.x[i]),
        y: indices.map(i => result.peak.y[i]),
        z: indices.map(i => result.peak.z[i])
      }
    };

    // 4. 如果数据点太多，进行智能采样
    if (sortedResult.timestamps.length > this.displayWindowSize) {
      return this.intelligentSample(sortedResult, this.displayWindowSize);
    }

    return sortedResult;
  }

  /**
   * 智能采样（保持数据特征）
   */
  intelligentSample(data, targetSize) {
    if (data.timestamps.length <= targetSize) {
      return data;
    }

    const step = data.timestamps.length / targetSize;
    const sampledData = {
      timestamps: [],
      rms: { x: [], y: [], z: [] },
      peak: { x: [], y: [], z: [] }
    };

    for (let i = 0; i < targetSize; i++) {
      const index = Math.floor(i * step);
      sampledData.timestamps.push(data.timestamps[index]);
      sampledData.rms.x.push(data.rms.x[index]);
      sampledData.rms.y.push(data.rms.y[index]);
      sampledData.rms.z.push(data.rms.z[index]);
      sampledData.peak.x.push(data.peak.x[index]);
      sampledData.peak.y.push(data.peak.y[index]);
      sampledData.peak.z.push(data.peak.z[index]);
    }

    return sampledData;
  }

  /**
   * 计算显示窗口开始时间（显示完整的10分钟范围）
   */
  calculateWindowStart(endTime) {
    return endTime - (10 * 60 * 1000); // 固定显示10分钟范围
  }

  /**
   * 格式化时间戳为显示字符串
   */
  formatTimestamp(timestamp) {
    const date = new Date(timestamp);
    return date.toLocaleTimeString('zh-CN', {
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit'
    });
  }

  /**
   * 生成唯一的时间标签，避免重复显示
   */
  generateUniqueTimeLabels(timestamps) {
    if (!timestamps || timestamps.length === 0) {
      return [];
    }

    const labels = [];
    const labelCounts = new Map(); // 记录每个标签出现的次数

    for (let i = 0; i < timestamps.length; i++) {
      const timestamp = timestamps[i];
      let baseLabel = this.formatTimestamp(timestamp);

      // 检查是否已经存在相同的标签
      if (labelCounts.has(baseLabel)) {
        const count = labelCounts.get(baseLabel);
        labelCounts.set(baseLabel, count + 1);

        // 为重复的标签添加序号或更精确的时间信息
        const date = new Date(timestamp);
        const milliseconds = date.getMilliseconds();

        if (milliseconds > 0) {
          // 如果有毫秒信息，使用毫秒
          baseLabel = `${baseLabel.split('.')[0]}.${milliseconds.toString().padStart(3, '0')}`;
        } else {
          // 否则添加序号
          baseLabel = `${baseLabel}(${count})`;
        }
      } else {
        labelCounts.set(baseLabel, 1);
      }

      labels.push(baseLabel);
    }

    return labels;
  }

  /**
   * 获取空的显示数据
   */
  getEmptyDisplayData() {
    return {
      timeData: [],
      valueData: { x: [], y: [], z: [] },
      metadata: {
        totalPoints: 0,
        timeRange: { start: null, end: null },
        hasHistoricalData: false,
        hasRealtimeData: false
      }
    };
  }

  /**
   * 清空历史数据
   */
  clearHistoricalData(deviceId) {
    const device = this.devices.get(deviceId);
    if (!device) return;

    const historical = device.historicalData;
    historical.timestamps.length = 0;
    historical.rms.x.length = 0;
    historical.rms.y.length = 0;
    historical.rms.z.length = 0;
    historical.peak.x.length = 0;
    historical.peak.y.length = 0;
    historical.peak.z.length = 0;
    historical.isLoaded = false;
    historical.loadTime = null;
    historical.timeRange.start = null;
    historical.timeRange.end = null;
  }

  /**
   * 设置显示窗口
   */
  setDisplayWindow(deviceId, startTime, endTime) {
    const device = this.devices.get(deviceId);
    if (!device) return;

    device.displayState.currentWindowStart = startTime;
    device.displayState.currentWindowEnd = endTime;
    device.displayState.autoScroll = false; // 手动设置窗口时关闭自动滚动

    this.addPendingUpdate(deviceId);
    this.throttledUpdate();
  }

  /**
   * 启用/禁用自动滚动
   */
  setAutoScroll(deviceId, enabled) {
    const device = this.devices.get(deviceId);
    if (!device) return;

    device.displayState.autoScroll = enabled;

    if (enabled) {
      // 重新计算窗口到最新数据
      const latestTime = this.getLatestTimestamp(device);
      if (latestTime) {
        device.displayState.currentWindowEnd = latestTime;
        device.displayState.currentWindowStart = this.calculateWindowStart(latestTime);
      }
    }
  }

  /**
   * 获取最新时间戳
   */
  getLatestTimestamp(device) {
    let latestTime = null;

    // 检查实时数据
    if (device.realtimeData.timestamps.length > 0) {
      latestTime = device.realtimeData.timestamps[device.realtimeData.timestamps.length - 1];
    }

    // 如果没有实时数据，检查历史数据
    if (!latestTime && device.historicalData.isLoaded && device.historicalData.timestamps.length > 0) {
      latestTime = device.historicalData.timestamps[device.historicalData.timestamps.length - 1];
    }

    return latestTime;
  }

  /**
   * 添加待更新设备
   */
  addPendingUpdate(deviceId) {
    this.pendingUpdates.add(deviceId);
  }

  /**
   * 触发更新事件
   */
  triggerUpdate() {
    if (this.pendingUpdates.size === 0) return;

    const updateList = Array.from(this.pendingUpdates);
    this.pendingUpdates.clear();

    // 触发更新事件
    if (this.updateCallback) {
      this.updateCallback(updateList);
    }

    this.lastUpdateTime = Date.now();
  }

  /**
   * 节流函数
   */
  throttle(func, delay) {
    let timeoutId;
    let lastExecTime = 0;

    return function (...args) {
      const currentTime = Date.now();

      if (currentTime - lastExecTime > delay) {
        func.apply(this, args);
        lastExecTime = currentTime;
      } else {
        clearTimeout(timeoutId);
        timeoutId = setTimeout(() => {
          func.apply(this, args);
          lastExecTime = Date.now();
        }, delay - (currentTime - lastExecTime));
      }
    };
  }

  /**
   * 设置更新回调
   */
  setUpdateCallback(callback) {
    this.updateCallback = callback;
  }

  /**
   * 获取设备元数据
   */
  getDeviceMetadata(deviceId) {
    const device = this.devices.get(deviceId);
    return device ? device.metadata : {};
  }

  /**
   * 获取设备状态
   */
  getDeviceStatus(deviceId) {
    const device = this.devices.get(deviceId);
    if (!device) return null;

    return {
      hasHistoricalData: device.historicalData.isLoaded,
      historicalDataPoints: device.historicalData.timestamps.length,
      realtimeDataPoints: device.realtimeData.dataCount,
      timeRange: {
        historical: device.historicalData.timeRange,
        realtime: {
          start: device.realtimeData.timestamps[0] || null,
          end: device.realtimeData.timestamps[device.realtimeData.timestamps.length - 1] || null
        }
      },
      displayWindow: {
        start: device.displayState.currentWindowStart,
        end: device.displayState.currentWindowEnd,
        autoScroll: device.displayState.autoScroll
      },
      lastUpdate: device.realtimeData.lastUpdateTime
    };
  }

  /**
   * 清理设备数据
   */
  clearDevice(deviceId) {
    this.devices.delete(deviceId);
    this.pendingUpdates.delete(deviceId);
    console.log(`🗑️ 设备 ${deviceId} 数据已清理`);
  }

  /**
   * 获取所有设备ID
   */
  getAllDeviceIds() {
    return Array.from(this.devices.keys());
  }
}

export default ChartDataManager;
